package xw4g08.rkb;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.openrdf.model.BNode;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.http.HTTPRepository;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.RDFWriter;
import org.openrdf.rio.Rio;

import xw4g08.Configuration;

public class RkbStat {

	static String conf = Configuration.BASE_DIR + File.separator + "rkb.txt";
	static Map<String,Service> services = new HashMap<String,Service>();
	
	public static void main(String[] args) {

		parse(conf);
		write(Configuration.OUT_DIR + File.separator + "rkb.n3");
	
	}
	
	static private void parse(String input){
		File file = new File(input);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
	        String line = null;
	        while ((line = reader.readLine()) != null) {
	        	if(line.startsWith("#"))
	        		continue;
	        	String[] stat = line.split(" ");
	        	Service ser = services.get(stat[0]);
	        	if(ser == null) {
	        		ser = new Service(stat[0],stat[1]);
	        		services.put(stat[0], ser);
	        	}
	        	ser.put(stat[2], stat[3]);
	        }
	        reader.close();
	      
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void write(String output) {
		FileOutputStream out;
		try {
			out = new FileOutputStream(Configuration.BASE_DIR+File.separator +"rkb.n3");
			RDFWriter writer = Rio.createWriter(RDFFormat.N3, out);
			try {
				writer.startRDF();
				HTTPRepository rep = new HTTPRepository("http://southampton.rkbexplorer.com/sparql/");
				RepositoryConnection con = rep.getConnection();
				ValueFactory vf = con.getValueFactory();
				String sd = "http://darq.sf.net/dose/0.1#";
				URI sd_capability = vf.createURI(sd, "capability");
				URI sd_triples = vf.createURI(sd, "triples");
				URI sd_pre = vf.createURI(sd, "predicate");
				URI sd_totalTriples = vf.createURI(sd, "totalTriples");
				URI sd_url = vf.createURI(sd, "url");
				writer.handleNamespace("sd", "http://darq.sf.net/dose/0.1#");
			/*	RepositoryResult<Namespace> nmSpaces = con.getNamespaces();
				while(nmSpaces.hasNext()){
					Namespace ns = nmSpaces.next();
					writer.handleNamespace(ns.getPrefix(),ns.getName());
				}
				nmSpaces.close();*/
				
				Set<String> urls = services.keySet();
				
				for(String u:urls) {
					int index = u.indexOf(".");
					//String[] tem = u.split(".");
					String head = u.substring(0, index);
					BNode servNode = vf.createBNode(head);
					Statement sta = vf.createStatement(servNode, RDF.TYPE, vf.createURI(sd,"Service"));//[] a sd:Service;
					writer.handleStatement(sta);
					Service ser = services.get(u);
					Map<String, String> preStats = ser.get();
					Set<String> pres = preStats.keySet();
					int j = 0;
					for(String pre:pres) {
						BNode capNode = vf.createBNode(head+"cap"+"-"+(j++));
						Value p = vf.createURI(pre);
						sta = vf.createStatement(servNode, sd_capability, capNode);
						writer.handleStatement(sta);
						sta = vf.createStatement(capNode, sd_pre, p);
						writer.handleStatement(sta);
						sta = vf.createStatement(capNode, sd_triples, vf.createLiteral(preStats.get(pre)));
						writer.handleStatement(sta);
					}
					
					writer.handleStatement(vf.createStatement(servNode, sd_totalTriples, vf.createLiteral(ser.total)));
					writer.handleStatement(vf.createStatement(servNode, sd_url, vf.createURI("http://"+u+"/sparql/")));
					writer.handleComment("#############################");
					
				}
				con.close();
				rep.shutDown();
				writer.endRDF();
			} catch (RDFHandlerException e) {
				e.printStackTrace();
			} catch (RepositoryException e) {
				e.printStackTrace();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		
	}

}

class Service {
	String url;
	String total;
	Map<String,String> predicates = new HashMap<String,String>();
	
	public Service(String url, String total) {
		this.url = url;
		this.total = total;
	}
	
	public void put(String predicate, String num) {
		predicates.put(predicate, num);
	}
	
	public Map<String, String> get() {
		return predicates;
	}
	
	@Override
	public boolean equals(Object o) {
		if(o instanceof Service) {
			if(((Service) o).url == this.url)
				return true;
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return this.url.hashCode()*7;
	}
}